﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using MySerialPort.ClassFiles;
using System.IO.Ports;
using System.Text.RegularExpressions;
namespace MySerialPort
{
    public partial class SerialPortFul : UserControl
    {
        mySerialPort COM;
        public SerialPortFul()
        {
            InitializeComponent();
            Dashboard_Init();
            UpdateUI_Init();
           // this.SerialPortDataReceived += process;
            // QueueReceiveEnable();
        }

        private void process(object obj)
        {
            MessageBox.Show(obj.ToString());
        }

        private void cBoxCom_DropDown(object sender, EventArgs e)
        {
            cBoxCom.DataSource = SerialPort.GetPortNames();

        }

        List<string> listBaudRate = new List<string>();
        private void Dashboard_Init()
        {
            cBoxCom.DataSource = SerialPort.GetPortNames();
            listBaudRate.Insert(0, "4800");
            listBaudRate.Insert(1, "9600");
            listBaudRate.Insert(2, "19200");
            listBaudRate.Insert(3, "115200");
            listBaudRate.Insert(4, "125000");
            listBaudRate.Insert(5, "128000");
            listBaudRate.Insert(6, "230400");
            listBaudRate.Insert(7, "250000");
            listBaudRate.Insert(8, "256000");
            listBaudRate.Insert(9, "312500");
            listBaudRate.Insert(10, "384000");
            listBaudRate.Insert(11, "500000");
            listBaudRate.Insert(12, "自定义");
            cBoxBaudRate.DataSource = listBaudRate.ToArray();
            cBoxBaudRate.SelectedIndex = 11;

            List<string> list = new List<string>();
            cBoxCom.DropDownStyle = ComboBoxStyle.DropDownList;
            list.Clear();
            list.Insert(0, "4");
            list.Insert(1, "5");
            list.Insert(2, "6");
            list.Insert(3, "7");
            list.Insert(4, "8");
            cBoxDataBit.DataSource = list.ToArray();
            cBoxDataBit.SelectedIndex = 4;
            cBoxDataBit.DropDownStyle = ComboBoxStyle.DropDownList;
            list.Clear();
            list.Insert(0, "偶");
            list.Insert(1, "奇");
            list.Insert(2, "无");
            cBoxCompart.DataSource = list.ToArray();
            cBoxCompart.SelectedIndex = 2;
            cBoxCompart.DropDownStyle = ComboBoxStyle.DropDownList;
            list.Clear();
            list.Insert(0, "0");
            list.Insert(1, "1");
            list.Insert(2, "1.5");
            list.Insert(3, "2");
            cBoxStopBit.DataSource = list.ToArray();
            cBoxStopBit.SelectedIndex = 1;
            cBoxStopBit.DropDownStyle = ComboBoxStyle.DropDownList;
            btnOption.Text = "打开";
            btnStatus.Text = "状态：关闭";
            btnStatus.BackColor = Color.Red;
        }
        private void cBoxBaudRate_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (cBoxBaudRate.SelectedIndex == 12)
            {
                cBoxBaudRate.DropDownStyle = System.Windows.Forms.ComboBoxStyle.Simple;
            }
            else
            {
                cBoxBaudRate.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
            }
        }
        private void cBoxBaudRate_Leave(object sender, EventArgs e)
        {
            listBaudRate.Add(cBoxBaudRate.Text);
            cBoxBaudRate.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;

            cBoxBaudRate.DataSource = listBaudRate;
        }


        private void btnOption_Click(object sender, EventArgs e)
        {
            if (btnOption.Text != "关闭")
            {
                if (string.IsNullOrEmpty(cBoxCom.Text)) { MessageBox.Show("没有可打开的串口"); return; }

                if (COM != null)
                {
                    COM = null;
                }
                COM = new mySerialPort(checkBoxRTS.Checked, checkBoxDTR.Checked, cBoxCom.SelectedValue.ToString(),
                   Convert.ToInt32(cBoxBaudRate.Text), Convert.ToInt32(cBoxDataBit.Text),
                   cBoxCompart.SelectedIndex == 0 ? (Parity.Even) :
                   (cBoxCompart.SelectedIndex == 1 ? Parity.Odd :
                   Parity.None),
                    cBoxStopBit.SelectedIndex == 0 ? (StopBits.None) :
                    (cBoxStopBit.SelectedIndex == 1 ? StopBits.One :
                     (cBoxStopBit.SelectedIndex == 2 ? StopBits.OnePointFive :
                     StopBits.Two)),
                     new MySerialPort.ClassFiles.mySerialPort.SerialPortOutputDelegate(GetOutputHandle));
                COM.UsingQueue = QueueReceive;
                if (COM.OpenConnection())
                {
                    btnStatus.Text = "状态：打开";
                    btnStatus.BackColor = Color.Green;
                    btnOption.Text = "关闭";
                }
                else
                {
                    btnStatus.Text = "状态：关闭";
                    btnStatus.BackColor = Color.Red;
                    COM = null;
                }

            }
            else
            {
                if (COM.IsConnected() == MySerialPort.ClassFiles.mySerialPort.SerialPortStatus.Open)
                {
                    COM = null;
                    btnOption.Text = "打开";
                    btnStatus.Text = "状态：关闭";
                    btnStatus.BackColor = Color.Red;
                }
            }
        }
        bool QueueReceive = false;
        public void QueueReceiveEnable()
        {
            QueueReceive = true;
        }
        public void QueueReceiveDisable()
        {
            QueueReceive = false;
        }


        public delegate void DataReceiveEventHandler(object obj);
        public event DataReceiveEventHandler SerialPortDataReceived;
        int RxNumber = 0;
        int TxNumber = 0;
        private Queue<List<byte>> _msgQueue = new Queue<List<byte>>();
        private List<byte> _data = new List<byte>();
        public void GetOutputHandle(object obj)
        {
            if (COM.UsingQueue)
            {
                List<byte> lb = (obj as List<byte>);
                byte[] bb = lb.ToArray();
                RxNumber += lb.Count;
                _msgQueue.Enqueue(lb);
                linklabelRxNumber.Invoke(UpdateUIReadCallbackHandle, bb);
                if (SerialPortDataReceived != null)
                {
                    SerialPortDataReceived.Invoke(bb);
                } 
            }
            else
            {
                byte[] bb = (obj as byte[]);
                RxNumber += bb.Length;
                _data.AddRange(bb);
                linklabelRxNumber.Invoke(UpdateUIReadCallbackHandle, bb);
                if (SerialPortDataReceived != null)
                {
                    SerialPortDataReceived.Invoke(bb);
                } 
            }
        }
        public int ClearReceiveEvent()
        {
            int i = 0;
            if (SerialPortDataReceived != null)
            {
                Delegate[] dels = SerialPortDataReceived.GetInvocationList();
                foreach (Delegate del in dels)
                {
                    object delObj = del.GetType().GetProperty("Method").GetValue(del, null);
                    string funcName = (string)delObj.GetType().GetProperty("Name").GetValue(delObj, null);////方法名
                    Console.WriteLine(funcName);
                    SerialPortDataReceived -= del as DataReceiveEventHandler;
                    i++;
                }
            }
            return i;
        }
        private delegate void UpdateUIDelegateHandle(object obj);
        UpdateUIDelegateHandle UpdateUIReadCallbackHandle;
        UpdateUIDelegateHandle UpdateUIWriteCallbackHandle;
        void UpdateUI_Init()
        {
            UpdateUIReadCallbackHandle = new UpdateUIDelegateHandle(UpdatePerformRead);

            UpdateUIWriteCallbackHandle = new UpdateUIDelegateHandle(UpdatePerformWrite);
        }

        private void UpdatePerformWrite(object obj)
        {
            linklabelTxNumber.Text = TxNumber.ToString();
        }
        private void UpdatePerformRead(object o)
        {
            if (checkBoxHexMode.Checked)
            {
                richTextBox1.Text += BitConverter.ToString((o as byte[]));
            }
            else
            {
                richTextBox1.Text += Encoding.Default.GetString(o as byte[]);
            }
            linklabelRxNumber.Text = RxNumber.ToString();
         
        }

        private void btnClear_Click(object sender, EventArgs e)
        {
            linklabelRxNumber.Text = linklabelTxNumber.Text = "0";
            RxNumber = 0;
            TxNumber = 0;
        }


        public bool Write(byte[] _content)
        {
            if (COM.ForwardBytes(_content))
            {
                TxNumber += _content.Length;
                linklabelTxNumber.Invoke(UpdateUIWriteCallbackHandle,null);
                return true;
            }
            else
            {
                return false;
            }
        }
        public bool Write(bool IsHex, object _content)
        {
            byte[] contentBytes;
            if (IsHex)
            {
                contentBytes = MyUtility.ByteConvertor.ToHexByteArray((string)_content);
            }
            else
            {
                contentBytes = MyUtility.ByteConvertor.ToByteArray((string)_content);
            }

            if (COM.ForwardBytes(contentBytes))
            {
                TxNumber += contentBytes.Length;
                linklabelTxNumber.Invoke(UpdateUIWriteCallbackHandle, null);
                return true;
            }
            else
            {
                return false;
            }
        }

        private void btnForward_Click(object sender, EventArgs e)
        {
            Write(checkBoxHexMode.Checked, richTextBoxForward.Text);
        }
    }
}

